#include "menubutton.h"

#include <QPainter>

MenuButton::MenuButton(QWidget *parent) : QToolButton(parent) {
  m_nPaddingLeft = 5;
  m_nPaddingRight = 5;
  m_nPaddingTop = 5;
  m_nPaddingBottom = 5;
  m_textAlign = TextAlign_Left;

  m_bShowTriangle = false;
  m_nTriangleLen = 5;
  m_trianglePosition = TrianglePosition_Right;
  m_triangleColor = QColor(255, 255, 255);

  m_bShowIcon = false;
  m_nIconSpace = 0;
  m_iconSize = QSize(16, 16);
  m_pixIconNormal = QPixmap();
  m_pixIconHover = QPixmap();
  m_pixIconCheck = QPixmap();

  m_bShowLine = true;
  m_nLineSpace = 0;
  m_nLineWidth = 5;
  m_linePosition = LinePosition_Left;
  m_lineColor = QColor(0, 187, 158);

  m_normalBgColor = QColor(230, 230, 230);
  m_hoverBgColor = QColor(130, 130, 130);
  m_checkBgColor = QColor(80, 80, 80);

  m_normalTextColor = QColor(100, 100, 100);
  m_hoverTextColor = QColor(255, 255, 255);
  m_checkTextColor = QColor(255, 255, 255);

  m_normalBgBrush = Qt::NoBrush;
  m_hoverBgBrush = Qt::NoBrush;
  m_checkBgBrush = Qt::NoBrush;

  m_bHover = false;
  setCheckable(false);
  setText(QStringLiteral("tool"));
}

//////////////////////////////////////////////////

int MenuButton::getPaddingLeft() const { return m_nPaddingLeft; }

int MenuButton::getPaddingRight() const { return m_nPaddingRight; }

int MenuButton::getPaddingTop() const { return m_nPaddingTop; }

int MenuButton::getPaddingBottom() const { return m_nPaddingBottom; }

MenuButton::TextAlign MenuButton::getTextAlign() const { return m_textAlign; }

//////////////////////////////////////////////////

bool MenuButton::getShowTriangle() const { return m_bShowTriangle; }

int MenuButton::getTriangleLen() const { return m_nTriangleLen; }

MenuButton::TrianglePosition MenuButton::getTrianglePosition() const {
  return m_trianglePosition;
}

QColor MenuButton::getTriangleColor() const { return m_triangleColor; }

//////////////////////////////////////////////////

bool MenuButton::getShowIcon() const { return m_bShowIcon; }

int MenuButton::getIconSpace() const { return m_nIconSpace; }

QSize MenuButton::getIconSize() const { return m_iconSize; }

QPixmap MenuButton::getIconNormal() const { return m_pixIconNormal; }

QPixmap MenuButton::getIconHover() const { return m_pixIconHover; }

QPixmap MenuButton::getIconCheck() const { return m_pixIconCheck; }

//////////////////////////////////////////////////

bool MenuButton::getShowLine() const { return m_bShowLine; }

int MenuButton::getLineSpace() const { return m_nLineSpace; }

int MenuButton::getLineWidth() const { return m_nLineWidth; }

MenuButton::LinePosition MenuButton::getLinePosition() const {
  return m_linePosition;
}

QColor MenuButton::getLineColor() const { return m_lineColor; }

//////////////////////////////////////////////////

QColor MenuButton::getNormalBgColor() const { return m_normalBgColor; }

QColor MenuButton::getHoverBgColor() const { return m_hoverBgColor; }

QColor MenuButton::getCheckBgColor() const { return m_checkBgColor; }

QColor MenuButton::getNormalTextColor() const { return m_normalTextColor; }

QColor MenuButton::getHoverTextColor() const { return m_hoverTextColor; }

QColor MenuButton::getCheckTextColor() const { return m_checkTextColor; }

//////////////////////////////////////////////////

void MenuButton::setPaddingLeft(int paddingLeft) {
  if (m_nPaddingLeft != paddingLeft) {
    m_nPaddingLeft = paddingLeft;
    this->update();
  }
}

void MenuButton::setPaddingRight(int paddingRight) {
  if (m_nPaddingRight != paddingRight) {
    m_nPaddingRight = paddingRight;
    this->update();
  }
}

void MenuButton::setPaddingTop(int paddingTop) {
  if (m_nPaddingTop != paddingTop) {
    m_nPaddingTop = paddingTop;
    this->update();
  }
}

void MenuButton::setPaddingBottom(int paddingBottom) {
  if (m_nPaddingBottom != paddingBottom) {
    m_nPaddingBottom = paddingBottom;
    this->update();
  }
}

void MenuButton::setPadding(int padding) {
  setPadding(padding, padding, padding, padding);
}

void MenuButton::setPadding(int paddingLeft, int paddingRight, int paddingTop,
                            int paddingBottom) {
  m_nPaddingLeft = paddingLeft;
  m_nPaddingRight = paddingRight;
  m_nPaddingTop = paddingTop;
  m_nPaddingBottom = paddingBottom;
  this->update();
}

//////////////////////////////////////////////////

void MenuButton::setTextAlign(const MenuButton::TextAlign &textAlign) {
  if (m_textAlign != textAlign) {
    m_textAlign = textAlign;
    this->update();
  }
}

void MenuButton::setShowTriangle(bool bShowTriangle) {
  if (m_bShowTriangle != bShowTriangle) {
    m_bShowTriangle = bShowTriangle;
    this->update();
  }
}

void MenuButton::setTriangleLen(int triangleLen) {
  if (m_nTriangleLen != triangleLen) {
    m_nTriangleLen = triangleLen;
    this->update();
  }
}

void MenuButton::setTrianglePosition(
    const MenuButton::TrianglePosition &trianglePosition) {
  if (m_trianglePosition != trianglePosition) {
    m_nTriangleLen = trianglePosition;
    this->update();
  }
}

void MenuButton::setTriangleColor(const QColor &triangleColor) {
  if (m_triangleColor != triangleColor) {
    m_triangleColor = triangleColor;
    this->update();
  }
}

//////////////////////////////////////////////////

void MenuButton::setShowIcon(bool showIcon) {
  if (m_bShowIcon != showIcon) {
    m_bShowIcon = showIcon;
    this->update();
  }
}

void MenuButton::setIconSpace(int iconSpace) {
  if (m_nIconSpace != iconSpace) {
    m_nIconSpace = iconSpace;
    this->update();
  }
}

void MenuButton::setIconSize(const QSize &iconSize) {
  if (m_iconSize != iconSize) {
    m_iconSize = iconSize;
    this->update();
  }
}

void MenuButton::setIconNormal(const QPixmap &iconNormal) {
  if (m_pixIconNormal.cacheKey() != iconNormal.cacheKey())
  // if(m_pixIconNormal != iconNormal)
  {
    m_pixIconNormal = iconNormal;
    this->update();
  }
}

void MenuButton::setIconUnused(const QPixmap &iconUnused) {
  if (m_pixIconUnused.cacheKey() != iconUnused.cacheKey()) {
    m_pixIconUnused = iconUnused;
    this->update();
  }
}
void MenuButton::setIconHover(const QPixmap &iconHover) {
  if (m_pixIconHover.cacheKey() != iconHover.cacheKey()) {
    m_pixIconHover = iconHover;
    this->update();
  }
}

void MenuButton::setIconCheck(const QPixmap &iconCheck) {
  if (m_pixIconCheck.cacheKey() != iconCheck.cacheKey()) {
    m_pixIconCheck = iconCheck;
    this->update();
  }
}

//////////////////////////////////////////////////

void MenuButton::setShowLine(bool bShowLine) {
  if (m_bShowLine != bShowLine) {
    m_bShowLine = bShowLine;
    this->update();
  }
}

void MenuButton::setLineSpace(int nLineSpace) {
  if (m_nLineSpace != nLineSpace) {
    m_nLineSpace = nLineSpace;
    this->update();
  }
}

void MenuButton::setLineWidth(int nLineWidth) {
  if (m_nLineWidth != nLineWidth) {
    m_nLineWidth = nLineWidth;
    this->update();
  }
}

void MenuButton::setLinePosition(const MenuButton::LinePosition &linePosition) {
  if (m_linePosition != linePosition) {
    m_linePosition = linePosition;
    this->update();
  }
}

void MenuButton::setLineColor(const QColor &lineColor) {
  if (m_lineColor != lineColor) {
    m_lineColor = lineColor;
    this->update();
  }
}

//////////////////////////////////////////////////

void MenuButton::setNormalBgColor(const QColor &normalBgColor) {
  if (m_normalBgColor != normalBgColor) {
    m_normalBgColor = normalBgColor;
    this->update();
  }
}

// 设置灰色背景颜色
void MenuButton::setUnenableBgColor(const QColor &unenableBgColor) {
  if (m_unusedBgColor != unenableBgColor) {
    m_unusedBgColor = unenableBgColor;
    this->update();
  }
}

void MenuButton::setHoverBgColor(const QColor &hoverBgColor) {
  if (m_hoverBgColor != hoverBgColor) {
    m_hoverBgColor = hoverBgColor;
    this->update();
  }
}

void MenuButton::setCheckBgColor(const QColor &checkBgColor) {
  if (m_checkBgColor != checkBgColor) {
    m_checkBgColor = checkBgColor;
    this->update();
  }
}
void MenuButton::setNormalTextColor(const QColor &normalTextColor) {
  if (m_normalTextColor != normalTextColor) {
    m_normalTextColor = normalTextColor;
    this->update();
  }
}

void MenuButton::setHoverTextColor(const QColor &hoverTextColor) {
  if (m_hoverTextColor != hoverTextColor) {
    m_hoverTextColor = hoverTextColor;
    this->update();
  }
}

void MenuButton::setCheckTextColor(const QColor &checkTextColor) {
  if (m_checkTextColor != checkTextColor) {
    m_checkTextColor = checkTextColor;
    this->update();
  }
}

//////////////////////////////////////////////////

void MenuButton::setNormalBgBrush(const QBrush &normalBgBrush) {
  if (m_normalBgBrush != normalBgBrush) {
    m_normalBgBrush = normalBgBrush;
    this->update();
  }
}

void MenuButton::setHoverBgBrush(const QBrush &hoverBgBrush) {
  if (m_hoverBgBrush != hoverBgBrush) {
    m_hoverBgBrush = hoverBgBrush;
    this->update();
  }
}

void MenuButton::setCheckBgBrush(const QBrush &checkBgBrush) {
  if (m_checkBgBrush != checkBgBrush) {
    m_checkBgBrush = checkBgBrush;
    this->update();
  }
}

//////////////////////////////////////////////////

QSize MenuButton::sizeHint() const { return QSize(30, 30); }

QSize MenuButton::minimumSizeHint() const { return QSize(28, 28); }

//////////////////////////////////////////////////

// void MenuButton::enterEvent(QEvent *) {
//   m_bHover = true;
//   this->update();
// }

void MenuButton::leaveEvent(QEvent *) {
  m_bHover = false;
  this->update();
}

void MenuButton::paintEvent(QPaintEvent *) {
  // 绘制准备工作，启用反锯齿
  QPainter painter(this);
  painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

  // 绘制背景
  drawBg(&painter);
  // 绘制文字
  // drawText(&painter);
  // 绘制图标
  drawIcon(&painter);
  // 绘制边框线条
  drawLine(&painter);
  // 绘制倒三角
  drawTriangle(&painter);
}

//////////////////////////////////////////////////

void MenuButton::drawBg(QPainter *painter) {
  painter->save();
  painter->setPen(Qt::NoPen);

  int width = this->width();
  int height = this->height();

  QRect bgRect;
  if (m_linePosition == LinePosition_Left) {
    bgRect = QRect(m_nLineSpace, 0, width - m_nLineSpace, height);
  } else if (m_linePosition == LinePosition_Right) {
    bgRect = QRect(0, 0, width - m_nLineSpace, height);
  } else if (m_linePosition == LinePosition_Top) {
    bgRect = QRect(0, m_nLineSpace, width, height - m_nLineSpace);
  } else if (m_linePosition == LinePosition_Bottom) {
    bgRect = QRect(0, 0, width, height - m_nLineSpace);
  } else {
    bgRect = QRect(0, 0, width, height);
  }

  // 如果画刷存在，则取画刷
  QBrush bgBrush;
  if (isChecked()) {
    bgBrush = m_checkBgBrush;
  } else if (m_bHover) {
    bgBrush = m_hoverBgBrush;
  }
  //    else if(!isEnabled())
  //    {
  //        bgBrush = m_unusedBgColor;
  //    }
  else {
    bgBrush = m_normalBgBrush;
  }

  if (bgBrush != Qt::NoBrush) {
    painter->setBrush(bgBrush);
  } else {
    // 根据当前状态选择对应颜色
    QColor bgColor;
    if (isChecked()) {
      bgColor = m_checkBgColor;
    } else if (m_bHover) {
      bgColor = m_hoverBgColor;
    }
    //        else if(!isEnabled())
    //        {
    //            bgBrush = m_unusedBgColor;
    //        }
    else {
      bgColor = m_normalBgColor;
    }
    painter->setBrush(bgColor);
  }
  painter->drawRect(bgRect);
  painter->restore();
}

void MenuButton::drawText(QPainter *painter) {
  painter->save();
  painter->setBrush(Qt::NoBrush);

  // 根据当前状态选择对应颜色
  QColor textColor;
  if (isChecked()) {
    textColor = m_checkTextColor;
  } else if (m_bHover) {
    textColor = m_hoverTextColor;
  }
  //    else if(!isEnabled())
  //    {
  //        textColor = m_unusedBgColor;
  //    }
  else {
    textColor = m_normalTextColor;
  }

  QRect textRect = QRect(m_nPaddingLeft, m_nPaddingTop,
                         width() - m_nPaddingLeft - m_nPaddingRight,
                         height() - m_nPaddingTop - m_nPaddingBottom);
  painter->setPen(textColor);
  painter->drawText(textRect, m_textAlign | Qt::AlignVCenter, text());
  painter->restore();
}

void MenuButton::drawIcon(QPainter *painter) {
  if (!m_bShowIcon) {
    return;
  }
  painter->save();
  QPixmap pixmap;
  if (isChecked()) {
    pixmap = m_pixIconCheck;
  } else if (m_bHover) {
    pixmap = m_pixIconHover;
  } else if (!isEnabled()) {
    pixmap = m_pixIconUnused;
  } else {
    pixmap = m_pixIconNormal;
  }

  if (!pixmap.isNull()) {
    // 等比例平滑缩放图标
    pixmap = pixmap.scaled(m_iconSize, Qt::KeepAspectRatio,
                           Qt::SmoothTransformation);
    painter->drawPixmap(m_nIconSpace, (height() - m_iconSize.height()) / 2,
                        pixmap);
  }
  painter->restore();
}

void MenuButton::drawLine(QPainter *painter) {
  if (!m_bShowLine) {
    return;
  }
  if (!isChecked()) {
    return;
  }
  if (m_linePosition == LinePosition_None) {
    return;
  }

  painter->save();

  QPen pen;
  pen.setWidth(m_nLineWidth);
  pen.setColor(m_lineColor);
  painter->setPen(pen);

  // 根据线条位置设置线条坐标
  QPoint pointStart;
  QPoint pointEnd;
  if (m_linePosition == LinePosition_Left) {
    pointStart = QPoint(0, 0);
    pointEnd = QPoint(0, height());
  } else if (m_linePosition == LinePosition_Right) {
    pointStart = QPoint(width(), 0);
    pointEnd = QPoint(width(), height());
  } else if (m_linePosition == LinePosition_Top) {
    pointStart = QPoint(0, 0);
    pointEnd = QPoint(width(), 0);
  } else if (m_linePosition == LinePosition_Bottom) {
    pointStart = QPoint(0, height());
    pointEnd = QPoint(width(), height());
  }
  painter->drawLine(pointStart, pointEnd);
  painter->restore();
}

void MenuButton::drawTriangle(QPainter *painter) {
  if (!m_bShowTriangle) {
    return;
  }

  // 选中或者悬停显示
  if (!m_bHover && !isChecked()) {
    return;
  }

  painter->save();
  painter->setPen(Qt::NoPen);
  painter->setBrush(m_triangleColor);

  // 绘制在右侧中间，根据设定的倒三角的边长设定三个点位置
  int width = this->width();
  int height = this->height();
  int midWidth = width / 2;
  int midHeight = height / 2;

  QPolygon pts;
  if (m_trianglePosition == TrianglePosition_Left) {
    pts.setPoints(3, m_nTriangleLen, midHeight, 0, midHeight - m_nTriangleLen,
                  0, midHeight + m_nTriangleLen);
  } else if (m_trianglePosition == TrianglePosition_Right) {
    pts.setPoints(3, width - m_nTriangleLen, midHeight, width,
                  midHeight - m_nTriangleLen, width,
                  midHeight + m_nTriangleLen);
  } else if (m_trianglePosition == TrianglePosition_Top) {
    pts.setPoints(3, midWidth, m_nTriangleLen, midWidth - m_nTriangleLen, 0,
                  midWidth + m_nTriangleLen, 0);
  } else if (m_trianglePosition == TrianglePosition_Bottom) {
    pts.setPoints(3, midWidth, height - m_nTriangleLen,
                  midWidth - m_nTriangleLen, height, midWidth + m_nTriangleLen,
                  height);
  }
  painter->drawPolygon(pts);
  painter->restore();
}
